#include "Record_WAV.h"
#include "string.h"
#include "WM8960.h"
#include "sai.h"
#include "stm32H7xx_hal.h"
#include "gpio.h"
#include "stdio.h"

uint8_t CloseFileFlag;    //1:already open file have to close it.

uint8_t EndFileFlag;      //1:reach the wave file end;
                          //2:wait for last transfer;
                          //3:finish transfer stop dma.

__IO uint8_t FillBufFlag; //0:fill first half buf;
                          //1:fill second half buf;
                          //0xFF:do nothing.

FIL WAV_File;             //File struct

wavctrl WaveCtrlData;     //Play control struct

uint32_t Audio_LastBytes; //The WAV file last bytes to play

uint8_t WAV_Buffer[WAV_BUFFER_SIZE] = {0};  //The buffer of record.
uint8_t WAV_BufferSend[WAV_BUFFER_SIZE] = {0};  //The buffer of play.

__WaveHeader WAV_Header;  //The file head of WAV file

char RecFileName[30];     //The name of the record head

__IO uint32_t RecDataSize;

REC_FLAG Rec_Flag;        //The flag of recording state

uint32_t WriteSize;       //The byte numbers of writing to file every time.

uint8_t I2S_Callback_Flag = 0;

uint8_t I2S_Half_Callback_Flag = 0;


/**
  * @brief  Open the WAV file, get the message of the file.
  * @param  None
  * @retval None
  */
void Strat_Record(void) {

  uint8_t res;
  FRESULT Res;
  
  Rec_Flag = NOT_START;
  
  printf("Press JOY_CTRL to start record !!\r\n");
  while(Rec_Flag == NOT_START)
  {
//    Key_Control();
	  if(HAL_GetTick() >= 1000)
	  {
		  Rec_Flag = START_REC;
	  }
  }
  printf("Record start !\r\n");
  
  res = WAV_File_Init();
  printf("WAV_File_Init = %d\r\n",res);
  
  if(res != 0){
    return;
  }


  
  HAL_SAI_Receive_DMA(&hsai_BlockB3, WAV_Buffer, WAV_BUFFER_SIZE/2);
  HAL_SAI_Transmit_DMA(&hsai_BlockA3,(uint8_t*)WAV_BufferSend,  WAV_BUFFER_SIZE/2);
  
  while((Rec_Flag==START_REC)||(Rec_Flag==PAUSE_REC)) {
    
    if(I2S_Half_Callback_Flag == 1) {
      I2S_Half_Callback_Flag = 0;
      res = f_write(&WAV_File,WAV_Buffer,WAV_BUFFER_SIZE/2,&WriteSize);
      RecDataSize += WriteSize;
      printf("f_write: %d, WriteSize: %d\r\n", res, WriteSize);
    }
    
    if(I2S_Callback_Flag == 1) {
      I2S_Callback_Flag = 0;
      res = f_write(&WAV_File,(WAV_Buffer+(WAV_BUFFER_SIZE/2)),WAV_BUFFER_SIZE/2,&WriteSize);
      RecDataSize += WriteSize;
      printf("f_write: %d, WriteSize: %d\r\n", res, WriteSize);
    }
    else  {
//      Key_Control();
    	if(HAL_GetTick() >= 60000)
		{
			Rec_Flag = STOP_REC;
		}
    }
  }
  WAV_Header.riff.ChunkSize = RecDataSize+36;   //File size - 8;
  WAV_Header.data.ChunkSize = RecDataSize;      //Data size
  printf("RecDataSize=%d\r\n",RecDataSize);
  
  f_sync(&WAV_File);
  Res=f_lseek(&WAV_File,0);										  //offset to file head.
  printf("res=%d\r\n",Res);
  
  Res=f_write(&WAV_File,(const void*)(&WAV_Header),sizeof(__WaveHeader),&WriteSize);  //write file head
  printf("f_write=%d\r\n",Res);
  
  Res=f_close(&WAV_File);
	printf("f_close=%d\r\n",Res);
  
	printf("Record stop\r\n");
}

/**
  * @brief  Initialize WAV file
  * @param  None
  * @retval None
  */
uint8_t WAV_File_Init(void) {
  
	FRESULT Res;
	uint16_t i;
  
	WAV_Header.riff.ChunkID=0X46464952;                   //"RIFF"
	WAV_Header.riff.ChunkSize=0;                          //Not yet determined, final calculation required
	WAV_Header.riff.Format=0X45564157;                    //"WAVE"
	WAV_Header.fmt.ChunkID=0X20746D66;                    //"fmt "
	WAV_Header.fmt.ChunkSize=16;                          //16 bytes
	WAV_Header.fmt.AudioFormat=0X01;                      //0X01, lineal PCM;0X03, IMA ADPCM
 	WAV_Header.fmt.NumOfChannels=2;                       //dual channel
 	WAV_Header.fmt.SampleRate=16000;                      //16Khz sampling rate
 	WAV_Header.fmt.ByteRate=WAV_Header.fmt.SampleRate*4;  //Byte rate = sampling rate * number of channels * (ADC bit number/8)
 	WAV_Header.fmt.BlockAlign=4;                          //Chunk size = channel number *(ADC /8)
 	WAV_Header.fmt.BitsPerSample=16;                      //16-bit PCM
    WAV_Header.data.ChunkID=0X61746164;                   //"data"
 	WAV_Header.data.ChunkSize=0;                          //Data size, final calculation required
  
  for(i=0;i<100;i++)  {
		sprintf(RecFileName,"0:/music/rec%d.wav",i);
		printf("%s\r\n",RecFileName);
		Res=f_open(&WAV_File,RecFileName,FA_CREATE_NEW | FA_WRITE);
    
		if(Res==FR_EXIST)
			continue;
		else if(Res==FR_OK)  {
			CloseFileFlag=1;
			Res=f_write(&WAV_File,(const void*)(&WAV_Header),sizeof(__WaveHeader),&WriteSize);//write file head
			printf("File_Header f_write : %d\r\n", Res);
			break;
		}
		else  {
			printf("f_open: %d\r\n",Res);
			return 1;   //Create new file error
		}
	}
  printf("File created completed !!\r\n");
	return 0;       //Create new file completed
}

/**
  * @brief  Handle Key press.
  * @param  Press_Hold_Time: The time when the key was pressed.
  * @retval None
  */
void Rec_Key_Handle(uint32_t Press_Hold_Time) {
  if(Press_Hold_Time == 0)  {
    if(Rec_Flag == NOT_START) {
      Rec_Flag = START_REC;
      printf("START_REC!!\r\n");
    }
    else if(Rec_Flag == START_REC)  {
      Rec_Flag = PAUSE_REC;
      printf("PAUSE_REC!!\r\n");
      HAL_SAI_DMAPause(&hsai_BlockB3);
    }
    else if(Rec_Flag == PAUSE_REC)  {
      Rec_Flag = START_REC;
      printf("START_REC!!\r\n");
      HAL_SAI_DMAResume(&hsai_BlockB3);
    }
  }
  else  {
    if(Rec_Flag != NOT_START) {
      Rec_Flag = STOP_REC;
      printf("STOP_REC!!\r\n");
      HAL_SAI_DMAStop(&hsai_BlockB3);
    }
  }
}

